
extern "C"
{
extern POBJECT_TYPE *IoDriverObjectType;

typedef NTSTATUS (__stdcall *NtProtectVirtualMemory)( IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN OUT PULONG NumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG OldAccessProtection ); 

typedef NTSTATUS (__stdcall *MiProtectVirtualMemory) (
    IN PEPROCESS Process,
    IN PVOID *BaseAddress,
    IN PULONG RegionSize,
    IN ULONG NewProtect,
    IN PULONG LastProtect);

NTSTATUS NTAPI ObReferenceObjectByName(PUNICODE_STRING ObjectPath,
                                       ULONG Attributes,
                                       PACCESS_STATE PassedAccessState,
                                       ACCESS_MASK DesiredAccess,
                                       POBJECT_TYPE ObjectType,
                                       KPROCESSOR_MODE AccessMode,
                                       PVOID ParseContext,
                                       PVOID* ObjectPtr);
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
                                  IN POBJECT_TYPE ObjectType,
                                  IN KPROCESSOR_MODE AccessMode,
                                  IN PACCESS_STATE PassedAccessState,
                                  IN ACCESS_MASK DesiredAccess,
                                  IN OUT PVOID ParseContext,
                                  OUT PHANDLE Handle);

typedef struct _CONNECT_DATA {
    IN PDEVICE_OBJECT ClassDeviceObject;
    IN PVOID ClassService;
} CONNECT_DATA, *PCONNECT_DATA;

typedef struct   {
    //
    // Pointer back to the this extension's device object.
    //
    PDEVICE_OBJECT      Self;

    PKINTERRUPT InterruptObject;

    //
    // The spin lock guarding the object's ISR
    //
    KSPIN_LOCK          InterruptSpinLock;         

    //
    // The top of the stack before this filter was added.  AKA the location
    // to which all IRPS should be directed.
    //
    PDEVICE_OBJECT      TopOfStack;

    //
    // "THE PDO"  (ejected by root)
    //
    PDEVICE_OBJECT      PDO;

    //
    // Remove tracking
    //
    IO_REMOVE_LOCK RemoveLock;

    //
    // The IRP sent to the device to power it to D0
    //
    PIRP OutstandingPowerIrp;

    //
    // Current power state that the device is in
    //
    DEVICE_POWER_STATE PowerState;

    //
    // Current power state that the system in in
    //
    SYSTEM_POWER_STATE SystemState;

    POWER_ACTION ShutdownType; 

    // 
    // Number of input data items currently in the InputData queue
    //
    ULONG InputCount;

    //
    // Reference count for number of keyboard enables.
    //
    LONG EnableCount;

    //
    // Timer used to retry the ISR DPC routine when the class
    // driver is unable to consume all the port driver's data.
    //
    KTIMER DataConsumptionTimer;

    //
    // DPC queue for completion of requests that fail by exceeding
    // the maximum number of retries.
    //
    KDPC RetriesExceededDpc;

    //
    // DPC queue for logging overrun and internal driver errors.
    //
    KDPC ErrorLogDpc;

    //
    // DPC queue for command timeouts.
    //
    KDPC TimeOutDpc;

    //
    // DPC queue for resetting the device 
    //
    KDPC ResetDpc;

    //
    // Request sequence number (used for error logging).
    //
    ULONG SequenceNumber;

    //
    // Class connection data.
    //
    CONNECT_DATA ConnectData;


} *PCOMMON_DATA;


typedef VOID (__stdcall * kbd_call_t)(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PKEYBOARD_INPUT_DATA  InputDataStart,
    IN PKEYBOARD_INPUT_DATA  InputDataEnd,
    IN OUT PULONG  InputDataConsumed
    );
typedef VOID  (__stdcall *mou_call_t)(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PMOUSE_INPUT_DATA  InputDataStart,
    IN PMOUSE_INPUT_DATA  InputDataEnd,
    IN OUT PULONG  InputDataConsumed
    );
typedef NTSTATUS (__stdcall *AddDevice_t)(
    IN PDRIVER_OBJECT  DriverObject,
    IN PDEVICE_OBJECT  PhysicalDeviceObject 
    );
};